package org.vacoor.nothing.web.misc.codegen;

import org.vacoor.nothing.common.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Types;

/**
 */
public class SimpleMapper implements EntityMapper {

    @Override
    public String getEntityName(String tableName) {
        tableName = StringUtils.hasText(tableName) ? tableName : ("Unnamed" + (new java.util.Date()).getTime());
        if (tableName.toUpperCase().startsWith("T_")) {
            tableName = tableName.substring(2);
        } else if (tableName.toUpperCase().startsWith("TB_")) {
            tableName = tableName.substring(3);
        }
        return StringUtils.underscoreToCamelCase(tableName, true);
    }

    @Override
    public String getJavaTypeFullName(String column, String type, int sqlType, int length, int precision) {
        return getJavaType(column, type, sqlType, length, precision).getName();
    }

    protected Class<?> getJavaType(String column, String type, int sqlType, int length, int precision) {
        if (Types.TINYINT == sqlType) {
            return Byte.class;
        }
        if (Types.SMALLINT == sqlType) {
            return Short.class;
        }
        if (Types.INTEGER == sqlType) {
            return Integer.class;
        }
        if (Types.BIGINT == sqlType) {
            return Long.class;
        }
        if (Types.FLOAT == sqlType) {
            return Float.class;
        }
        if (Types.DOUBLE == sqlType) {
            return Double.class;
        }
        if (Types.NUMERIC == sqlType || Types.DECIMAL == sqlType) {
            if (0 != precision) {
                return BigDecimal.class;
                // fix status, type number(1) --> Boolean TODO 是否这些应该是枚举??
            } else if (1 == length && null != column && !column.toUpperCase().endsWith("STATUS") && !column.toUpperCase().endsWith("TYPE")) {
                return Boolean.class;
            }
            return length < 10 ? Integer.class : (length < 19 ? Long.class : BigInteger.class);
        }
        if (Types.CHAR == sqlType) {
            return 1 == length ? Boolean.class : Character.class;
        }
        if (Types.BIT == sqlType) {
            return Boolean.class;
        }
        if (Types.VARCHAR == sqlType || Types.NVARCHAR == sqlType || Types.CLOB == sqlType) {
            return String.class;
        }
        // TODO char 1 特殊处理 boolean
        if (Types.DATE == sqlType || Types.TIME == sqlType || Types.TIMESTAMP == sqlType) {
            return java.util.Date.class;
        }
        if (Types.VARBINARY == sqlType || Types.BLOB == sqlType) {
            return byte[].class;
        }

        // fix oracle NVARCHAR2 sql type is 1111 (Types.OTHER)
        if (Types.OTHER == sqlType && "NVARCHAR2".equals(type)) {
            return String.class;
        }
        throw new IllegalStateException(String.format("Column(%s) Unknown sqlType(%s)", column, sqlType));
    }
}
